// Go作者版权所有。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

// +构建忽略

package main

import "strings"

// 笔记：
// -小于64位的整数类型存在于寄存器的低位部分。
// 现在，上面的部分是垃圾；符号/零扩展可能会在将来进行优化，但目前还没有。
// -布尔类型为零或1；存储在字节中，但使用AMOVBZ加载，因此寄存器的上部字节为零。
// -*常量指令可能使用大于指令编码的常量。
// 在这种情况下，汇编程序扩展到多条指令并使用tmp
// 寄存器（R31）。

var regNamesPPC64 = []string{
	"R0", // REGZERO，未使用，但简化了regalloc中的计数
	"SP", // REGSP
	"SB", // REGSB
	"R3",
	"R4",
	"R5",
	"R6",
	"R7",
	"R8",
	"R9",
	"R10",
	"R11", // 用于闭包的REGCTXT
	"R12",
	"R13", // 规则
	"R14",
	"R15",
	"R16",
	"R17",
	"R18",
	"R19",
	"R20",
	"R21",
	"R22",
	"R23",
	"R24",
	"R25",
	"R26",
	"R27",
	"R28",
	"R29",
	"g",   // 雷格。使用名称“g”并设置Config.hasGReg使其成为“刚好发生”。
	"R31", // REGTMP

	"F0",
	"F1",
	"F2",
	"F3",
	"F4",
	"F5",
	"F6",
	"F7",
	"F8",
	"F9",
	"F10",
	"F11",
	"F12",
	"F13",
	"F14",
	"F15",
	"F16",
	"F17",
	"F18",
	"F19",
	"F20",
	"F21",
	"F22",
	"F23",
	"F24",
	"F25",
	"F26",
	"F27",
	"F28",
	"F29",
	"F30",
	"F31",

	// 如果添加寄存器，请在运行时更新asyncPreempt。

	// “CR0”，
	// “CR1”，
	// “CR2”，
	// “CR3”，
	// “CR4”，
	// “CR5”，
	// “CR6”，
	// “CR7”，

	// “CR”，
	// “XER”，
	// “LR”，
	// “CTR”，
}

func init() {
	// 将reg名称映射到reg整数。
	if len(regNamesPPC64) > 64 {
		panic("too many registers")
	}
	num := map[string]int{}
	for i, name := range regNamesPPC64 {
		num[name] = i
	}
	buildReg := func(s string) regMask {
		m := regMask(0)
		for _, r := range strings.Split(s, " ") {
			if n, ok := num[r]; ok {
				m |= regMask(1) << uint(n)
				continue
			}
			panic("register " + r + " not found")
		}
		return m
	}

	var (
		gp = buildReg("R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29")
		fp = buildReg("F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26")
		sp = buildReg("SP")
		sb = buildReg("SB")
		gr = buildReg("g")
		// cr=buildReg（“cr”）
		// ctr=buildReg（“ctr”）
		// lr=buildReg（“lr”）
		tmp     = buildReg("R31")
		ctxt    = buildReg("R11")
		callptr = buildReg("R12")
		// tls=buildReg（“R13”）
		gp01        = regInfo{inputs: nil, outputs: []regMask{gp}}
		gp11        = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
		gp21        = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}}
		gp21a0      = regInfo{inputs: []regMask{gp, gp | sp | sb}, outputs: []regMask{gp}}
		gp31        = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}}
		gp22        = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp, gp}}
		gp32        = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp, gp}}
		gp1cr       = regInfo{inputs: []regMask{gp | sp | sb}}
		gp2cr       = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}}
		crgp        = regInfo{inputs: nil, outputs: []regMask{gp}}
		crgp11      = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}
		crgp21      = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
		gpload      = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
		gploadidx   = regInfo{inputs: []regMask{gp | sp | sb, gp}, outputs: []regMask{gp}}
		gpstore     = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}}
		gpstoreidx  = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, gp | sp | sb}}
		gpstorezero = regInfo{inputs: []regMask{gp | sp | sb}} // ppc64.REGZERO是保留的零值
		gpxchg      = regInfo{inputs: []regMask{gp | sp | sb, gp}, outputs: []regMask{gp}}
		gpcas       = regInfo{inputs: []regMask{gp | sp | sb, gp, gp}, outputs: []regMask{gp}}
		fp01        = regInfo{inputs: nil, outputs: []regMask{fp}}
		fp11        = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
		fpgp        = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
		gpfp        = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
		fp21        = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
		fp31        = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
		fp2cr       = regInfo{inputs: []regMask{fp, fp}}
		fpload      = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{fp}}
		fploadidx   = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{fp}}
		fpstore     = regInfo{inputs: []regMask{gp | sp | sb, fp}}
		fpstoreidx  = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, fp}}
		callerSave  = regMask(gp | fp | gr)
		r3          = buildReg("R3")
		r4          = buildReg("R4")
		r5          = buildReg("R5")
		r6          = buildReg("R6")
	)
	ops := []opData{
		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true},     // arg0+arg1
		{name: "ADDconst", argLength: 1, reg: gp11, asm: "ADD", aux: "Int64"},     // arg0+生长素
		{name: "FADD", argLength: 2, reg: fp21, asm: "FADD", commutative: true},   // arg0+arg1
		{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true}, // arg0+arg1
		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                        // arg0-arg1
		{name: "SUBFCconst", argLength: 1, reg: gp11, asm: "SUBC", aux: "Int64"},  // 生长素-arg0（带进位）
		{name: "FSUB", argLength: 2, reg: fp21, asm: "FSUB"},                      // arg0-arg1
		{name: "FSUBS", argLength: 2, reg: fp21, asm: "FSUBS"},                    // arg0-arg1

		{name: "MULLD", argLength: 2, reg: gp21, asm: "MULLD", typ: "Int64", commutative: true}, // arg0*arg1（有符号64位）
		{name: "MULLW", argLength: 2, reg: gp21, asm: "MULLW", typ: "Int32", commutative: true}, // arg0*arg1（有符号32位）
		{name: "MULLDconst", argLength: 1, reg: gp11, asm: "MULLD", aux: "Int32", typ: "Int64"}, // arg0*生长素（有符号64位）
		{name: "MULLWconst", argLength: 1, reg: gp11, asm: "MULLW", aux: "Int32", typ: "Int64"}, // arg0*生长素（有符号64位）
		{name: "MADDLD", argLength: 3, reg: gp31, asm: "MADDLD", typ: "Int64"},                  // （arg0*arg1）+arg2（有符号64位）

		{name: "MULHD", argLength: 2, reg: gp21, asm: "MULHD", commutative: true},   // （arg0*arg1）>>64，已签名
		{name: "MULHW", argLength: 2, reg: gp21, asm: "MULHW", commutative: true},   // （arg0*arg1）>>32，已签名
		{name: "MULHDU", argLength: 2, reg: gp21, asm: "MULHDU", commutative: true}, // （arg0*arg1）>>64，未签名
		{name: "MULHWU", argLength: 2, reg: gp21, asm: "MULHWU", commutative: true}, // （arg0*arg1）>>32，未签名
		{name: "LoweredMuluhilo", argLength: 2, reg: gp22, resultNotInArgs: true},   // arg0*arg1，返回值（高，低）

		{name: "FMUL", argLength: 2, reg: fp21, asm: "FMUL", commutative: true},   // arg0*arg1
		{name: "FMULS", argLength: 2, reg: fp21, asm: "FMULS", commutative: true}, // arg0*arg1

		{name: "FMADD", argLength: 3, reg: fp31, asm: "FMADD"},   // arg0*arg1+arg2
		{name: "FMADDS", argLength: 3, reg: fp31, asm: "FMADDS"}, // arg0*arg1+arg2
		{name: "FMSUB", argLength: 3, reg: fp31, asm: "FMSUB"},   // arg0*arg1-arg2
		{name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS"}, // arg0*arg1-arg2

		{name: "SRAD", argLength: 2, reg: gp21, asm: "SRAD"}, // 带符号的arg0>>（arg1和127），64位宽度（注意：127，而不是63！）
		{name: "SRAW", argLength: 2, reg: gp21, asm: "SRAW"}, // 带符号的arg0>>（arg1和63），32位宽度
		{name: "SRD", argLength: 2, reg: gp21, asm: "SRD"},   // 无符号arg0>>（arg1和127），64位宽度
		{name: "SRW", argLength: 2, reg: gp21, asm: "SRW"},   // 无符号arg0>>（arg1和63），32位宽度
		{name: "SLD", argLength: 2, reg: gp21, asm: "SLD"},   // arg0<<（arg1和127），64位宽度
		{name: "SLW", argLength: 2, reg: gp21, asm: "SLW"},   // arg0<<（arg1和63），32位宽度

		{name: "ROTL", argLength: 2, reg: gp21, asm: "ROTL"},   // arg0向左旋转arg1 mod 64
		{name: "ROTLW", argLength: 2, reg: gp21, asm: "ROTLW"}, // uint32（arg0）向左旋转arg1 mod 32
		// 以下是实施ISA第C.8节所述的班次扩展助记符的ops。
		// 恒定移位值被压缩到aux int32中。
		{name: "RLDICL", argLength: 1, reg: gp11, asm: "RLDICL", aux: "Int32"},     // arg0提取移位参数标识的位“
		{name: "CLRLSLWI", argLength: 1, reg: gp11, asm: "CLRLSLWI", aux: "Int32"}, // None
		{name: "CLRLSLDI", argLength: 1, reg: gp11, asm: "CLRLSLDI", aux: "Int32"}, // None

		{name: "LoweredAdd64Carry", argLength: 3, reg: gp32, resultNotInArgs: true}, // arg0+arg1+进位，返回（和，进位）

		{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int64"}, // 有符号arg0>>生长素，0<=生长素<64，64位宽度
		{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int64"}, // 有符号arg0>>生长素，0<=生长素<32，32位宽度
		{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int64"},   // 无符号arg0>>生长素，0<=生长素<64，64位宽度
		{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int64"},   // 无符号arg0>>生长素，0<=生长素<32，32位宽度
		{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int64"},   // arg0<<生长素，0<=生长素<64，64位宽度
		{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int64"},   // arg0<<生长素，0<=生长素<32，32位宽度

		{name: "ROTLconst", argLength: 1, reg: gp11, asm: "ROTL", aux: "Int64"},   // arg0通过生长素位向左旋转
		{name: "ROTLWconst", argLength: 1, reg: gp11, asm: "ROTLW", aux: "Int64"}, // uint32（arg0）通过生长素位向左旋转
		{name: "EXTSWSLconst", argLength: 1, reg: gp11, asm: "EXTSWSLI", aux: "Int64"},

		{name: "RLWINM", argLength: 1, reg: gp11, asm: "RLWNM", aux: "Int64"},                      // 通过立即“rlwinm”旋转和遮罩。编码器PPC64RotateMask描述辅助
		{name: "RLWNM", argLength: 2, reg: gp21, asm: "RLWNM", aux: "Int64"},                       // 通过“rlwnm”旋转和遮罩。编码器PPC64RotateMask描述辅助
		{name: "RLWMI", argLength: 2, reg: gp21a0, asm: "RLWMI", aux: "Int64", resultInArg0: true}, // “rlwimi”与上述aux编码类似

		{name: "CNTLZD", argLength: 1, reg: gp11, asm: "CNTLZD", clobberFlags: true}, // 计数前导零
		{name: "CNTLZW", argLength: 1, reg: gp11, asm: "CNTLZW", clobberFlags: true}, // 计数前导零（32位）

		{name: "CNTTZD", argLength: 1, reg: gp11, asm: "CNTTZD"}, // 计数尾随的零
		{name: "CNTTZW", argLength: 1, reg: gp11, asm: "CNTTZW"}, // 计数尾随零（32位）

		{name: "POPCNTD", argLength: 1, reg: gp11, asm: "POPCNTD"}, // arg0中的设置位数
		{name: "POPCNTW", argLength: 1, reg: gp11, asm: "POPCNTW"}, // 放置在相应字中的arg0的每个字中的设置位数
		{name: "POPCNTB", argLength: 1, reg: gp11, asm: "POPCNTB"}, // 放置在相应字节中的arg0每个字节中的设置位数

		{name: "FDIV", argLength: 2, reg: fp21, asm: "FDIV"},   // arg0/arg1
		{name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS"}, // arg0/arg1

		{name: "DIVD", argLength: 2, reg: gp21, asm: "DIVD", typ: "Int64"},   // arg0/arg1（有符号64位）
		{name: "DIVW", argLength: 2, reg: gp21, asm: "DIVW", typ: "Int32"},   // arg0/arg1（有符号32位）
		{name: "DIVDU", argLength: 2, reg: gp21, asm: "DIVDU", typ: "Int64"}, // arg0/arg1（无符号64位）
		{name: "DIVWU", argLength: 2, reg: gp21, asm: "DIVWU", typ: "Int32"}, // arg0/arg1（无符号32位）

		{name: "MODUD", argLength: 2, reg: gp21, asm: "MODUD", typ: "UInt64"}, // arg0%arg1（无符号64位）
		{name: "MODSD", argLength: 2, reg: gp21, asm: "MODSD", typ: "Int64"},  // arg0%arg1（有符号64位）
		{name: "MODUW", argLength: 2, reg: gp21, asm: "MODUW", typ: "UInt32"}, // arg0%arg1（无符号32位）
		{name: "MODSW", argLength: 2, reg: gp21, asm: "MODSW", typ: "Int32"},  // arg0%arg1（有符号32位）
		// MOD实现为rem:=arg0-（arg0/arg1）*arg1

		// 转换都是浮点到浮点寄存器的操作。“整数”指FP寄存器中的编码。
		{name: "FCTIDZ", argLength: 1, reg: fp11, asm: "FCTIDZ", typ: "Float64"}, // 将浮点转换为64位整数向零舍入
		{name: "FCTIWZ", argLength: 1, reg: fp11, asm: "FCTIWZ", typ: "Float64"}, // 将浮点转换为32位整数向零舍入
		{name: "FCFID", argLength: 1, reg: fp11, asm: "FCFID", typ: "Float64"},   // 将64位整数转换为浮点
		{name: "FCFIDS", argLength: 1, reg: fp11, asm: "FCFIDS", typ: "Float32"}, // 将32位整数转换为浮点
		{name: "FRSP", argLength: 1, reg: fp11, asm: "FRSP", typ: "Float64"},     // 将浮点舍入为32位值

		// 浮点寄存器和整数寄存器之间的移动，位不变；通过PPC上的存储+加载完成。
		// 由于32位加载字面值位指令的可寻址性较差，因此总是将
		// 改为使用数据，并使用FMOVDload和FMOVDstore（这也将避免持久性问题）。
		// 应该应用一些优化--（Xi2f64（MOVWload（不是添加ptr+offset）））可以使用
		// 单词加载指令。（Xi2f64（移动加载ptr））可以是（移动加载ptr）

		{name: "MFVSRD", argLength: 1, reg: fpgp, asm: "MFVSRD", typ: "Int64"},   // 将F寄存器的64位移到G寄存器中
		{name: "MTVSRD", argLength: 1, reg: gpfp, asm: "MTVSRD", typ: "Float64"}, // 将G寄存器的64位移到F寄存器中

		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true},                    // arg0和arg1
		{name: "ANDN", argLength: 2, reg: gp21, asm: "ANDN"},                                     // arg0和^arg1
		{name: "ANDCC", argLength: 2, reg: gp2cr, asm: "ANDCC", commutative: true, typ: "Flags"}, // arg0和arg1集抄送
		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},                      // arg0 | arg1
		{name: "ORN", argLength: 2, reg: gp21, asm: "ORN"},                                       // arg0 | ^arg1
		{name: "ORCC", argLength: 2, reg: gp2cr, asm: "ORCC", commutative: true, typ: "Flags"},   // arg0 | arg1集CC
		{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true},                    // ^（arg0 | arg1）
		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", typ: "Int64", commutative: true},      // arg0^arg1
		{name: "XORCC", argLength: 2, reg: gp2cr, asm: "XORCC", commutative: true, typ: "Flags"}, // arg0^arg1设置CC
		{name: "EQV", argLength: 2, reg: gp21, asm: "EQV", typ: "Int64", commutative: true},      // arg0^^arg1
		{name: "NEG", argLength: 1, reg: gp11, asm: "NEG"},                                       // -arg0（整数）
		{name: "FNEG", argLength: 1, reg: fp11, asm: "FNEG"},                                     // -arg0（浮点）
		{name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"},                                   // sqrt（arg0）（浮点）
		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"},                                 // sqrt（arg0）（浮点，单精度）
		{name: "FFLOOR", argLength: 1, reg: fp11, asm: "FRIM"},                                   // 楼层（arg0），浮动64
		{name: "FCEIL", argLength: 1, reg: fp11, asm: "FRIP"},                                    // ceil（arg0），浮动64
		{name: "FTRUNC", argLength: 1, reg: fp11, asm: "FRIZ"},                                   // trunc（arg0），float64
		{name: "FROUND", argLength: 1, reg: fp11, asm: "FRIN"},                                   // 圆形（arg0），浮动64
		{name: "FABS", argLength: 1, reg: fp11, asm: "FABS"},                                     // abs（arg0），浮动64
		{name: "FNABS", argLength: 1, reg: fp11, asm: "FNABS"},                                   // -abs（arg0），浮动64
		{name: "FCPSGN", argLength: 2, reg: fp21, asm: "FCPSGN"},                                 // 复制符号arg0->arg1，浮动64

		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64"},                                                                                     // arg0 | aux
		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64"},                                                                                   // arg0^aux
		{name: "ANDconst", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}, asm: "ANDCC", aux: "Int64", clobberFlags: true}, // arg0和aux
		{name: "ANDCCconst", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}}, asm: "ANDCC", aux: "Int64", typ: "Flags"},                             // arg0&aux==0

		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB", typ: "Int64"},   // 符号扩展int8到int64
		{name: "MOVBZreg", argLength: 1, reg: gp11, asm: "MOVBZ", typ: "Int64"}, // 零位扩展uint8到uint64
		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH", typ: "Int64"},   // 符号扩展int16到int64
		{name: "MOVHZreg", argLength: 1, reg: gp11, asm: "MOVHZ", typ: "Int64"}, // 零扩展uint16到uint64
		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW", typ: "Int64"},   // 符号扩展int32到int64
		{name: "MOVWZreg", argLength: 1, reg: gp11, asm: "MOVWZ", typ: "Int64"}, // 零扩展uint32到uint64

		// 从arg0+aux+auxint以arch的endian顺序将字节加载到64位寄存器中。
		{name: "MOVBZload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // 加载字节零扩展
		{name: "MOVHload", argLength: 2, reg: gpload, asm: "MOVH", aux: "SymOff", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // 加载2字节符号扩展
		{name: "MOVHZload", argLength: 2, reg: gpload, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // 加载2字节零扩展
		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVW", aux: "SymOff", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},    // 加载4字节符号扩展
		{name: "MOVWZload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // 加载4字节零扩展
		{name: "MOVDload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", typ: "Int64", faultOnNilArg0: true, symEffect: "Read"},    // 加载8字节

		// 以arch的反尾端顺序将字节从arg0加载到64位寄存器中，全部为零扩展。
		// 生成的指令是索引加载，指令中没有偏移量字段，因此不使用辅助字段。
		// 在这些情况下，索引寄存器字段设置为0，完整地址位于基址寄存器中。
		{name: "MOVDBRload", argLength: 2, reg: gpload, asm: "MOVDBR", aux: "SymOff", typ: "Int64", faultOnNilArg0: true, symEffect: "Read"}, // 按相反顺序加载8字节
		{name: "MOVWBRload", argLength: 2, reg: gpload, asm: "MOVWBR", aux: "SymOff", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"}, // 按相反顺序加载4字节零扩展
		{name: "MOVHBRload", argLength: 2, reg: gpload, asm: "MOVHBR", aux: "SymOff", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"}, // 按相反顺序加载2字节零扩展

		// 在这些情况下，除了基址寄存器外，还使用索引寄存器
		// 从内存位置arg[0]+arg[1]加载。
		{name: "MOVBZloadidx", argLength: 3, reg: gploadidx, asm: "MOVBZ", typ: "UInt8"},  // 零位扩展uint8到uint64
		{name: "MOVHloadidx", argLength: 3, reg: gploadidx, asm: "MOVH", typ: "Int16"},    // 符号扩展int16到int64
		{name: "MOVHZloadidx", argLength: 3, reg: gploadidx, asm: "MOVHZ", typ: "UInt16"}, // 零扩展uint16到uint64
		{name: "MOVWloadidx", argLength: 3, reg: gploadidx, asm: "MOVW", typ: "Int32"},    // 符号扩展int32到int64
		{name: "MOVWZloadidx", argLength: 3, reg: gploadidx, asm: "MOVWZ", typ: "UInt32"}, // 零扩展uint32到uint64
		{name: "MOVDloadidx", argLength: 3, reg: gploadidx, asm: "MOVD", typ: "Int64"},
		{name: "MOVHBRloadidx", argLength: 3, reg: gploadidx, asm: "MOVHBR", typ: "Int16"}, // 符号扩展int16到int64
		{name: "MOVWBRloadidx", argLength: 3, reg: gploadidx, asm: "MOVWBR", typ: "Int32"}, // 符号扩展int32到int64
		{name: "MOVDBRloadidx", argLength: 3, reg: gploadidx, asm: "MOVDBR", typ: "Int64"},
		{name: "FMOVDloadidx", argLength: 3, reg: fploadidx, asm: "FMOVD", typ: "Float64"},
		{name: "FMOVSloadidx", argLength: 3, reg: fploadidx, asm: "FMOVS", typ: "Float32"},

		// 按arch的反尾端顺序将字节存储到arg0中。
		// 这些是索引存储，指令中没有偏移量字段，因此不使用生长素字段。
		{name: "MOVDBRstore", argLength: 3, reg: gpstore, asm: "MOVDBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 按相反顺序存储8字节
		{name: "MOVWBRstore", argLength: 3, reg: gpstore, asm: "MOVWBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 按相反顺序存储4字节
		{name: "MOVHBRstore", argLength: 3, reg: gpstore, asm: "MOVHBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 按相反顺序存储2字节

		// 来自arg0+aux+auxint的浮点加载
		{name: "FMOVDload", argLength: 2, reg: fpload, asm: "FMOVD", aux: "SymOff", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"}, // 负载双浮子
		{name: "FMOVSload", argLength: 2, reg: fpload, asm: "FMOVS", aux: "SymOff", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"}, // 负载单浮子

		// 按arch的endian顺序将字节存储到arg0+aux+auxint中
		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 存储字节
		{name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 存储2个字节
		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 存储4个字节
		{name: "MOVDstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 存储8字节

		// 将浮点值存储到arg0+aux+auxint中
		{name: "FMOVDstore", argLength: 3, reg: fpstore, asm: "FMOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 储存双弗洛特
		{name: "FMOVSstore", argLength: 3, reg: fpstore, asm: "FMOVS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 存储单个浮点数

		// 使用索引和基寄存器存储
		// 存储到arg[0]+arg[1]
		{name: "MOVBstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVB", typ: "Mem"},     // 再见
		{name: "MOVHstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVH", typ: "Mem"},     // 存储半个字
		{name: "MOVWstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVW", typ: "Mem"},     // 存储字
		{name: "MOVDstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVD", typ: "Mem"},     // 存储双字
		{name: "FMOVDstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVD", typ: "Mem"},   // 存储双浮点数
		{name: "FMOVSstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVS", typ: "Mem"},   // 存储单个浮点数
		{name: "MOVHBRstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVHBR", typ: "Mem"}, // 使用索引reg存储半字反向字节
		{name: "MOVWBRstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVWBR", typ: "Mem"}, // 使用索引reg存储字反转字节
		{name: "MOVDBRstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVDBR", typ: "Mem"}, // 使用索引reg存储双字反向字节

		// 以下操作将0存储到arg0+aux+auxint arg1=mem中
		{name: "MOVBstorezero", argLength: 2, reg: gpstorezero, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 存储零1字节
		{name: "MOVHstorezero", argLength: 2, reg: gpstorezero, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 存储零2字节
		{name: "MOVWstorezero", argLength: 2, reg: gpstorezero, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 存储零4字节
		{name: "MOVDstorezero", argLength: 2, reg: gpstorezero, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 存储零8字节

		{name: "MOVDaddr", argLength: 1, reg: regInfo{inputs: []regMask{sp | sb | gp}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVD", rematerializeable: true, symEffect: "Addr"}, // arg0+auxInt+aux（*gc.Sym），arg0=SP/SB/GP

		{name: "MOVDconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVD", typ: "Int64", rematerializeable: true}, // None
		{name: "FMOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "FMOVD", rematerializeable: true},           // None
		{name: "FMOVSconst", argLength: 0, reg: fp01, aux: "Float32", asm: "FMOVS", rematerializeable: true},           // None
		{name: "FCMPU", argLength: 2, reg: fp2cr, asm: "FCMPU", typ: "Flags"},

		{name: "CMP", argLength: 2, reg: gp2cr, asm: "CMP", typ: "Flags"},     // arg0与arg1进行比较
		{name: "CMPU", argLength: 2, reg: gp2cr, asm: "CMPU", typ: "Flags"},   // arg0与arg1进行比较
		{name: "CMPW", argLength: 2, reg: gp2cr, asm: "CMPW", typ: "Flags"},   // arg0与arg1进行比较
		{name: "CMPWU", argLength: 2, reg: gp2cr, asm: "CMPWU", typ: "Flags"}, // arg0与arg1进行比较
		{name: "CMPconst", argLength: 1, reg: gp1cr, asm: "CMP", aux: "Int64", typ: "Flags"},
		{name: "CMPUconst", argLength: 1, reg: gp1cr, asm: "CMPU", aux: "Int64", typ: "Flags"},
		{name: "CMPWconst", argLength: 1, reg: gp1cr, asm: "CMPW", aux: "Int32", typ: "Flags"},
		{name: "CMPWUconst", argLength: 1, reg: gp1cr, asm: "CMPWU", aux: "Int32", typ: "Flags"},

		// ISEL生长素值0=LT 1=GT 2=EQ arg2？arg0:arg1
		// ISEL生长素值4=GE 5=LE 6=NE arg2？arg1:arg0
		// ISELB特殊情况，其中对于布尔结果，arg0和arg1的值为0和1
		{name: "ISEL", argLength: 3, reg: crgp21, asm: "ISEL", aux: "Int32", typ: "Int32"},  // 见上文
		{name: "ISELB", argLength: 2, reg: crgp11, asm: "ISEL", aux: "Int32", typ: "Int32"}, // 见上文

		// 伪操作
		{name: "Equal", argLength: 1, reg: crgp},         // bool，true标志编码x==y，否则为false。
		{name: "NotEqual", argLength: 1, reg: crgp},      // 布尔，真标志编码x=否则我就错了。
		{name: "LessThan", argLength: 1, reg: crgp},      // bool，true标志编码x<y，否则为false。
		{name: "FLessThan", argLength: 1, reg: crgp},     // bool，true标志编码x<y，否则为false。
		{name: "LessEqual", argLength: 1, reg: crgp},     // bool，true标志编码x<=y，否则为false。
		{name: "FLessEqual", argLength: 1, reg: crgp},    // bool，true标志编码x<=y，否则为false；PPC<=！>哪一个对NaN来说是错误的
		{name: "GreaterThan", argLength: 1, reg: crgp},   // bool，true标志编码x>y，否则为false。
		{name: "FGreaterThan", argLength: 1, reg: crgp},  // bool，true标志编码x>y，否则为false。
		{name: "GreaterEqual", argLength: 1, reg: crgp},  // bool，true标志编码x>=y，否则为false。
		{name: "FGreaterEqual", argLength: 1, reg: crgp}, // bool，true标志编码x>=y，否则为false。；PPC>==！<哪一个对NaN来说是错误的

		// 调度器确保LoweredGetClosurePtr仅在入口块中发生，
		// 并将其排序到块的最开始，以防止其他
		// 使用闭包指针。
		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{ctxt}}, zeroWidth: true},

		// LoweredGetCallerSP返回当前函数调用方的SP。
		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},

		// LoweredGetCallerPC计算其“调用者”将返回的PC。
		// 也就是说，如果f调用g“calls”getcallerpc，
		// 结果应为g将返回到的f内的PC。
		// 有关更详细的讨论，请参阅runtime/stubs.go。
		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},

		// arg0=ptr，arg1=mem，返回void。如果ptr为零，则出现故障。
		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
		// 取整运算以阻止融合的乘加提取。
		{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
		{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},

		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                       // 调用静态函数aux。（*obj.LSym）。arg0=mem，auxint=argsize，返回mem
		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{callptr, ctxt, 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // 通过闭包调用函数。arg0=codeptr，arg1=closure，arg2=mem，auxint=argsize，返回mem
		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{callptr}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},            // 通过指针调用fn。arg0=codeptr，arg1=mem，auxint=argsize，返回mem

		// 大的或未对齐的归零
		// arg0=内存地址为零（在R3中，由于副作用而更改）
		// 返回mem
		// None
		// 当存在多个迭代时，将生成一个循环
		// 需要清除4个双字
		// None
		// XXLX或VS32，VS32，VS32
		// MOVD$len/32，31南非兰特
		// MOVD R31，中心
		// MOVD$16，R31
		// 循环：
		// STXVD2X VS32，（R0）（R3）
		// STXVD2X VS32，（R31），R3）
		// 加上R3,32
		// BC环路

		// 根据需要生成剩余的双字清除
		// MOVD R0，（R3）
		// MOVD R0,8（R3）
		// MOVD R0,16（R3）
		// MOVD R0,24（R3）

		// 其中一个或多个用于清除小于8字节的剩余部分
		// MOVW R0，n1（R3）
		// MOVH R0，n2（R3）
		// MOVB R0，n3（R3）
		{
			name:      "LoweredZero",
			aux:       "Int64",
			argLength: 2,
			reg: regInfo{
				inputs:   []regMask{buildReg("R20")},
				clobbers: buildReg("R20"),
			},
			clobberFlags:   true,
			typ:            "Mem",
			faultOnNilArg0: true,
			unsafePoint:    true,
		},
		{
			name:      "LoweredZeroShort",
			aux:       "Int64",
			argLength: 2,
			reg: regInfo{
				inputs: []regMask{gp}},
			typ:            "Mem",
			faultOnNilArg0: true,
			unsafePoint:    true,
		},
		{
			name:      "LoweredQuadZeroShort",
			aux:       "Int64",
			argLength: 2,
			reg: regInfo{
				inputs: []regMask{gp},
			},
			typ:            "Mem",
			faultOnNilArg0: true,
			unsafePoint:    true,
		},
		{
			name:      "LoweredQuadZero",
			aux:       "Int64",
			argLength: 2,
			reg: regInfo{
				inputs:   []regMask{buildReg("R20")},
				clobbers: buildReg("R20"),
			},
			clobberFlags:   true,
			typ:            "Mem",
			faultOnNilArg0: true,
			unsafePoint:    true,
		},

		// R31是临时寄存器
		// 循环代码：
		// MOVD len/32，R31设置回路中心
		// MOVD R31，中心
		// MOVD$16，R31索引寄存器
		// 循环：
		// LXVD2X（R0）（R4），VS32
		// LXVD2X（R31）（R4），VS33
		// 加上R4，$32增量src
		// STXVD2X VS32，（R0）（R3）
		// STXVD2X VS33，（R31）（R3）
		// 加上R3，$32增量dst
		// BC 16,0，环路分支中心
		// 为此，VS32和VS33被视为
		// 暂存器。因为regalloc没有
		// 跟踪向量寄存器，即使它可以被标记
		// 虽然遭到重击，但没有任何效果。
		// TODO:如果向量寄存器由regalloc管理
		// 将这些标记为Clobbred。
		// None
		// 未被此循环移动的字节将被移动
		// 结合以下说明，
		// 从最大尺寸开始，按以下方式生成
		// 根据需要，使用适当的偏移值。
		// movdn（R4），R14
		// MOVD R14，n（R3）
		// MOVW n1（R4），R14
		// MOVW R14，n1（R3）
		// MOVH n2（R4），R14
		// MOVH R14，n2（R3）
		// MOVB n3（R4），R14
		// MOVB R14，n3（R3）

		{
			name:      "LoweredMove",
			aux:       "Int64",
			argLength: 3,
			reg: regInfo{
				inputs:   []regMask{buildReg("R20"), buildReg("R21")},
				clobbers: buildReg("R20 R21"),
			},
			clobberFlags:   true,
			typ:            "Mem",
			faultOnNilArg0: true,
			faultOnNilArg1: true,
			unsafePoint:    true,
		},
		{
			name:      "LoweredMoveShort",
			aux:       "Int64",
			argLength: 3,
			reg: regInfo{
				inputs: []regMask{gp, gp},
			},
			typ:            "Mem",
			faultOnNilArg0: true,
			faultOnNilArg1: true,
			unsafePoint:    true,
		},

		// 以下内容类似于LoweredMove，但使用
		// LXV而不是LXVD2X，后者不需要索引
		// 注册并将在循环中执行4而不是仅执行4。
		{
			name:      "LoweredQuadMove",
			aux:       "Int64",
			argLength: 3,
			reg: regInfo{
				inputs:   []regMask{buildReg("R20"), buildReg("R21")},
				clobbers: buildReg("R20 R21"),
			},
			clobberFlags:   true,
			typ:            "Mem",
			faultOnNilArg0: true,
			faultOnNilArg1: true,
			unsafePoint:    true,
		},

		{
			name:      "LoweredQuadMoveShort",
			aux:       "Int64",
			argLength: 3,
			reg: regInfo{
				inputs: []regMask{gp, gp},
			},
			typ:            "Mem",
			faultOnNilArg0: true,
			faultOnNilArg1: true,
			unsafePoint:    true,
		},

		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},

		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, typ: "UInt8", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, typ: "UInt32", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, typ: "Int64", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
		{name: "LoweredAtomicLoadPtr", argLength: 2, reg: gpload, typ: "Int64", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},

		// 原子地址32，64
		// LWSYNC
		// LDAR（Rarg0），路由
		// 添加Rarg1，Rout
		// STDCCC路由（Rarg0）
		// BNE-3（个人电脑）
		// 退还新金额
		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},

		// 原子交换32，64
		// LWSYNC
		// LDAR（Rarg0），路由
		// STDCCC Rarg1（Rarg0）
		// BNE-2（个人电脑）
		// ISYNC
		// 返回旧val
		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},

		// 原子比较和交换。
		// arg0=指针，arg1=旧值，arg2=新值，arg3=内存。生长素必须为零。
		// 如果*arg0==arg1{
		// *arg0=arg2
		// 返回（真，内存）
		// }否则{
		// 返回（假，内存）
		// }
		// 同步
		// LDAR（Rarg0），Rtmp
		// CMP Rarg1，Rtmp
		// BNE 3（个人电脑）
		// STDCCC Rarg2（Rarg0）
		// BNE-4（个人电脑）
		// CBNZ Rtmp，-4（件）
		// CSET均衡，路由
		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, aux: "Int64", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, aux: "Int64", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},

		// 原子8/32和/或。
		// *arg0&=（|=）arg1。arg2=mem。返回内存。生长素必须为零。
		// LBAR/LWAT（Rarg0），Rtmp
		// 和/或Rarg1，Rtmp
		// STBCCC/STWCCC Rtmp（Rarg0），Rtmp
		// BNE Rtmp，-3（PC）
		{name: "LoweredAtomicAnd8", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true},
		{name: "LoweredAtomicAnd32", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true},
		{name: "LoweredAtomicOr8", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true},
		{name: "LoweredAtomicOr32", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true},

		// LoweredWB调用runtime.gcWriteBarrier。arg0=destptr，arg1=srcptr，arg2=mem，aux=runtime.gcWriteBarrier
		// 它保留R0到R17（特殊寄存器R1、R2、R11、R12、R13除外）、g及其参数R20和R21，
		// 但可能会破坏其他任何东西，包括R31（REGTMP）。
		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ buildReg("R0 R3 R4 R5 R6 R7 R8 R9 R10 R14 R15 R16 R17 R20 R21 g")) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},

		// 这些函数有三个，因此它们可以有三个不同的寄存器输入。
		// 当我们检查0<=c<=cap（A），然后检查0<=b<=c（b），然后检查0<=A<=b（c），我们需要
		// 要匹配的默认寄存器，因此我们不需要不必要地复制寄存器。
		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r6}}, typ: "Mem", call: true}, // arg0=idx，arg1=len，arg2=mem，返回内存。AuxInt包含报告代码（参见genericOps.go中的PanicBounds）。
		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r5}}, typ: "Mem", call: true}, // arg0=idx，arg1=len，arg2=mem，返回内存。AuxInt包含报告代码（参见genericOps.go中的PanicBounds）。
		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx，arg1=len，arg2=mem，返回内存。AuxInt包含报告代码（参见genericOps.go中的PanicBounds）。

		// （反转标志（CMP a b））==（CMP b a）
		// 所以如果我们想要（LessThan（cmpab）），但我们不能这样做，因为a是常数，
		// 然后我们做（LessThan（CMP b a）））。
		// 重写会将其转换为（大于（CMP b a））。
		// InvertFlags是一个伪操作，不能出现在程序集输出中。
		{name: "InvertFlags", argLength: 1}, // arg0的反向

		// 常量标志值。对于任何比较，有3种可能
		// 结果：签署的总订单中的三个（<，=，>）
		// 或未签名的总订单中的三个，取决于
		// 使用了比较操作（CMP或CMPU——PPC不同于
		// 其他体系结构，它们有一个单一的比较
		// 有符号和无符号比较结果。）

		// 这些ops供重写规则临时使用。他们
		// 无法显示在生成的程序集中。
		{name: "FlagEQ"}, // 相同的
		{name: "FlagLT"}, // 有符号<或无符号<
		{name: "FlagGT"}, // 已签名>或未签名>
	}

	blocks := []blockData{
		{name: "EQ", controls: 1},
		{name: "NE", controls: 1},
		{name: "LT", controls: 1},
		{name: "LE", controls: 1},
		{name: "GT", controls: 1},
		{name: "GE", controls: 1},
		{name: "FLT", controls: 1},
		{name: "FLE", controls: 1},
		{name: "FGT", controls: 1},
		{name: "FGE", controls: 1},
	}

	archs = append(archs, arch{
		name:            "PPC64",
		pkg:             "cmd/internal/obj/ppc64",
		genfile:         "../../ppc64/ssa.go",
		ops:             ops,
		blocks:          blocks,
		regnames:        regNamesPPC64,
		gpregmask:       gp,
		fpregmask:       fp,
		framepointerreg: int8(num["SP"]),
		linkreg:         -1, // 不用
	})
}
